package common

import (
	"fmt"
	"log"
	"math"
	"os"
	"reflect"

	"gopkg.in/yaml.v2"

	"xtsec.com/dns-syncer/common/tools"
)

const (
	projectName       = "dns-syncer"
	maxRequestTimeout = 30 // s
)

func init() {
	initSetting()
}

type requestConfig struct {
	Timeout int64 // second
}

type record struct {
	Name string  `yaml:"name"`
	ID   *string `yaml:"record_id"`
	RR   *string `yaml:"rr"`
	Type *string `yaml:"type"`
	TTL  *int64  `yaml:"ttl"` // 单位s 最小10分钟
}

type channel struct {
	Name    string   `yaml:"name"`
	Records []record `yaml:"records"`
}

type email struct {
	Host     string `yaml:"host"`
	Port     int    `yaml:"port"`
	From     string `yaml:"from"`
	Password string `yaml:"password"`
	To       string `yaml:"to"`
}

type Setting struct {
	DomainRecords []channel     `yaml:"domain_records"`
	Email         email         `yaml:"email"`
	RequestConfig requestConfig `yaml:"request_config"`
}

var setting = Setting{}

func initSetting() {
	basePath, _ := tools.GetProjectBaseDir(projectName)
	file, err := os.ReadFile(fmt.Sprintf("%s/%s", basePath, "conf/config.yaml"))
	if err != nil {
		log.Fatal("fail to read file:", err)
	}

	err = yaml.Unmarshal(file, &setting)
	if err != nil {
		log.Fatal("fail to yaml unmarshal:", err)
	}
}

func GetCONFWithDef(key, def string) string {
	v := reflect.ValueOf(&setting).Elem().FieldByName(key).String()
	if v != "" {
		return v
	}
	return def
}

func GetSetting() *Setting {
	return &setting
}

// GetRequestTimeout limit request timeout
func GetRequestTimeout() int64 {
	if setting.RequestConfig.Timeout <= 0 {
		return maxRequestTimeout
	}

	timeout := math.Min(float64(setting.RequestConfig.Timeout), float64(maxRequestTimeout))
	return int64(timeout)
}
